#include "bs_conf.h"

int bs_conf_read(bs_conf_t* pconf, const char* path){
    FILE*               file;
    char                buf[BS_LONG_STRLEN] = {0};
    _conf_elem_t        elem;
    int                 res;

    file=fopen(path, "r");
    if(file == NULL){
        return BS_NOTFOUND;
    }

    array_init(&pconf->list);
    while(fgets(buf, BS_LONG_STRLEN, file)){
        if(buf[0] == '#'){
            continue;
        }
        char* sig = strchr(buf, '=');
        if(sig==NULL){
            sig = strchr(buf, ':');
        }
        if(sig==NULL){
            continue;
        }
        char* name_sig = sig-1;
        while(name_sig-buf>=0 && bs_is_space(*name_sig)){
            name_sig--;
        }
        
        memset(&elem, 0, sizeof(_conf_elem_t));
        memcpy(elem.name, buf, name_sig-buf+1);
        elem.name[BS_LONG_STRLEN-1]='\0';
        char* value_sig = sig+1;
        while(value_sig<buf+BS_LONG_STRLEN && bs_is_space(*value_sig)){
            value_sig++;
        }
        memcpy(elem.value, value_sig, buf+BS_LONG_STRLEN-value_sig);
        elem.value[BS_LONG_STRLEN-1]='\0';
        int len = strlen(elem.value);
        if(!bs_is_char(elem.value[len-1])){
            elem.value[len-1]='\0';
        }
        if((res=array_push(&pconf->list, elem)) != BS_SUCCESS){
            fclose(file);
            return res;
        }
    }
    fclose(file);

    return BS_SUCCESS;
}

const char* bs_conf_getstr(const bs_conf_t* pconf, const char* name){
    uint32_t            i;
    _conf_elem_t*       elem;

    for(i=0; i<array_getlen(&pconf->list); i++){
        elem = (_conf_elem_t*)array_getptr(&pconf->list, i);
        if(strcmp(elem->name, name) == 0){
            return elem->value;
        }
    }

    return NULL;
}

int bs_conf_getint(const bs_conf_t* pconf, const char* name){
    uint32_t            i;
    _conf_elem_t*       elem;

    for(i=0; i<array_getlen(&pconf->list); i++){
        elem = (_conf_elem_t*)array_getptr(&pconf->list, i);
        if(strcmp(elem->name, name) == 0){
            return atoi(elem->value);
        }
    }

    return -1;
}

size_t bs_conf_size(const bs_conf_t* pconf){
    return array_getlen(&pconf->list);
}

const char* bs_conf_getname(const bs_conf_t* pconf, uint32_t i){
    if(i>=array_getlen(&pconf->list)){
        return NULL;
    }

    _conf_elem_t* elem = (_conf_elem_t*)array_getptr(&pconf->list, i);
    return elem->name;
}

const char* bs_conf_getstr_idx(const bs_conf_t* pconf, uint32_t i){
    if(i>=array_getlen(&pconf->list)){
        return NULL;
    }

    _conf_elem_t* elem = (_conf_elem_t*)array_getptr(&pconf->list, i);
    return elem->value;
}

int bs_conf_getint_idx(const bs_conf_t* pconf, uint32_t i){
    if(i>=array_getlen(&pconf->list)){
        return -1;
    }

    _conf_elem_t* elem = (_conf_elem_t*)array_getptr(&pconf->list, i);
    return atoi(elem->value);
}
